﻿using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

namespace Batman.Common.Extensions
{
    public static class ServiceCollectionExtension
    {
        /// <summary>
        /// 添加鉴权服务器配置 TODO: 被调用时会出错，需要排查原因
        /// </summary>
        /// <param name="service"></param>
        public static void AddIdentityServiceWithConfig(this IServiceCollection services, IHostingEnvironment env, string migrationsAssembly)
        {
            var configurationRoot = env.GetAppConfigurations();

            services.Configure<CookiePolicyOptions>(options =>
            {
                // This lambda determines whether user consent for non-essential cookies is needed for a given request.
                options.CheckConsentNeeded = context => true;
                options.MinimumSameSitePolicy = SameSiteMode.None;
            });

            var connectionString = configurationRoot.GetConnectionString("DefaultConnection");
            services.AddDbContext<IdentityDbContext>(options => options.UseSqlServer(connectionString));

            services.AddDefaultIdentity<IdentityUser>()
                    .AddEntityFrameworkStores<IdentityDbContext>()
                    .AddDefaultTokenProviders();

            // configure identity server with in-memory stores, keys, clients and scopes
            services.AddIdentityServer(options =>
            {
                var authorizationHost = env.GetAuthorizationHost();
                var uri = authorizationHost.GetUri();

                if (!string.IsNullOrWhiteSpace(uri))
                {
                    //修改配置的Issuer字段
                    options.IssuerUri = uri;
                    //授权跳转时，从batmant.identity的端口改为gateway的端口
                    options.PublicOrigin = uri;
                }
            })
            .AddDeveloperSigningCredential()
            .AddConfigurationStore(options =>
            {
                options.ConfigureDbContext = builder => builder.UseSqlServer(connectionString, sql => sql.MigrationsAssembly(migrationsAssembly));
            })
            .AddOperationalStore(options =>
            {
                options.ConfigureDbContext = builder => builder.UseSqlServer(connectionString, sql => sql.MigrationsAssembly(migrationsAssembly));
                options.EnableTokenCleanup = true;
                options.TokenCleanupInterval = 3600;
            })
            .AddAspNetIdentity<IdentityUser>();
        }

        /// <summary>
        /// Client添加到服务
        /// </summary>
        /// <param name="services"></param>
        /// <param name="env"></param>
        public static void AddAuthenticationWithConfig(this IServiceCollection services)
        {
            var env = services.BuildServiceProvider().GetService<IHostingEnvironment>();

            var authenticationInfo = env.GetAuthenticationInfo();

            services.AddAuthentication(options =>
            {
                options.DefaultScheme = authenticationInfo.ClientId;
                options.DefaultChallengeScheme = authenticationInfo.ClientId;
            })
            .AddCookie("Cookies") //开启会有Scheme already exists: UserManagement问题存在
            .AddOpenIdConnect(authenticationInfo.ClientId,
                              authenticationInfo.DisplayName,
                              options =>
            {
                options.RequireHttpsMetadata = false;
                options.ClientId = authenticationInfo.ClientId;
                options.Authority = authenticationInfo.Authority;
                options.SaveTokens = true;
            });
        }
    }
}
